/**
 * @author Administrator
 */
function firstTimeLoad(){
    moveToLoadView();
    loadFestival();
}

function secondTimeLoad(){
    moveToLoadView();
    initializeFestival();
}

function checkAppInstall(){
    var req = opensocial.newDataRequest();
    var params = {};
    params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL, opensocial.Person.Field.ADDRESSES, opensocial.Person.Field.AGE, opensocial.Person.Field.DATE_OF_BIRTH, opensocial.Person.Field.GENDER, opensocial.Person.Field.HAS_APP];
    req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, params), "viewer");
    req.send(function(response){
        if (response.hadError()) {
            // error logic
            var msg = response.getErrorMessage();
        }
        else {
            var item = response.get("viewer");
            if (!item.hadError()) {
                var viewer = item.getData();
                myID = viewer.getId();
                myName = viewer.getDisplayName();
                myURL = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
                gender = viewer.getField(opensocial.Person.Field.GENDER);
                hasApp = viewer.getField(opensocial.Person.Field.HAS_APP);
                // if viewer doesn't have application, move to application registration page
                if (hasApp == "false") {
					location.href = "http://mixi.jp/view_appli.pl?id=" + APP_ID;
				}
				else {//user has app
					// Gender Info
					// if user doesn't set gender, gender will set as male
					if (gender == undefined) {
						gender = 0;
					}
					else 
						if (gender.getKey() == "MALE") {
							gender = 0;
						}
						else {
							gender = 1;
						}
					
					firstTimeLoad();
				}
            }
            
        }
    });
}


function moveToLoadView(){
    document.getElementById("startView").style.display = "";
    document.getElementById("loadingStr").style.display = "";
    document.getElementById("nogame").style.display = "none";
    document.getElementById("finishGreeting").style.display = "none";
    document.getElementById("ruleWindow").style.display = "none";
    document.getElementById("fieldArea").style.display = "none";
    document.getElementById("fesitvalResultArea").style.display = "none";
    document.getElementById("personalResultArea").style.display = "none";
    gadgets.window.adjustHeight();
}

function moveToRuleView(){
    document.getElementById("startView").style.display = "";
    document.getElementById("loadingStr").style.display = "none";
    document.getElementById("nogame").style.display = "none";
    document.getElementById("finishGreeting").style.display = "none";
    document.getElementById("ruleWindow").style.display = "";
    document.getElementById("fieldArea").style.display = "none";
    document.getElementById("fesitvalResultArea").style.display = "none";
    document.getElementById("personalResultArea").style.display = "none";
    gadgets.window.adjustHeight();
}

function moveToFestival(){
    document.getElementById("startView").style.display = "none";
    document.getElementById("fieldArea").style.display = "";
    document.getElementById("fesitvalResultArea").style.display = "none";
    document.getElementById("personalResultArea").style.display = "none";
    gadgets.window.adjustHeight();
}

function moveToFestivalResult(){
    document.getElementById("startView").style.display = "none";
    document.getElementById("fieldArea").style.display = "none";
    document.getElementById("fesitvalResultArea").style.display = "";
    document.getElementById("personalResultArea").style.display = "none";
    gadgets.window.adjustHeight();
}

function moveToFestivalFinish(){
    document.getElementById("startView").style.display = "";
    document.getElementById("loadingStr").style.display = "none";
    document.getElementById("nogame").style.display = "none";
    document.getElementById("finishGreeting").style.display = "";
    document.getElementById("ruleWindow").style.display = "none";
    document.getElementById("fieldArea").style.display = "none";
    document.getElementById("fesitvalResultArea").style.display = "none";
    document.getElementById("personalResultArea").style.display = "none";
    gadgets.window.adjustHeight();
}

function loadFestival(){
    myID = "";
    myName = "";
    myURL = "";
    gender = 0;
    voiceText = new Array();
    diaryText = new Array();
    requestInfo = true;
    friendNumCheck();
}

function friendNumCheck(){
	// check tne number of friend
    friendNum = 0;
    var fparams = {};
    fparams[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
    fparams[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
    var fetchOpt = {};
    fetchOpt[opensocial.DataRequest.PeopleRequestFields.MAX] = 1;
    // create randam number
    var idSpec = opensocial.newIdSpec(fparams);
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPeopleRequest(idSpec, fetchOpt), "friends");
    /*   var params = {};
     params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL, opensocial.Person.Field.ADDRESSES, opensocial.Person.Field.AGE, opensocial.Person.Field.DATE_OF_BIRTH, opensocial.Person.Field.GENDER, opensocial.Person.Field.HAS_APP];
     req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, params), "viewer");
     */
    req.send(function(response){
        if (response.hadError()) {
            // error logic
            var msg = response.getErrorMessage();
            
        }
        else {
            /*  
             var item = response.get("viewer");
             if (!item.hadError()) {
             var viewer = item.getData();
             myID = viewer.getId();
             myName = viewer.getDisplayName();
             myURL = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
             gender = viewer.getField(opensocial.Person.Field.GENDER);
             hasApp = viewer.getField(opensocial.Person.Field.HAS_APP);
             // if viewer doesn't have application, move to application registration page
             if(!hasApp){
             location.href = "http://mixi.jp/view_appli.pl?id="+APP_ID;
             }
             // Gender Info
             // if user doesn't set gender, gender will set as male
             if (gender == undefined) {
             gender = 0;
             }
             else
             if (gender.getKey() == "MALE") {
             gender = 0;
             }
             else {
             gender = 1;
             }
             }
             */
            var friends = response.get('friends').getData();
            // get total friends number
            friendNum = friends.getTotalSize();
            initializeFestival();
        }
    });
}

function initializeFestival(){
    initializeVariables()
    createPlayerIDList();
}

function initializeVariables(){
    fieldTitle = "";
    fieldsList = new Object();
    fieldIDList = new Array();
    playerIDList = new Array();
    resultList = new Array();
    playerList = new Array();
    playerPointList = new Object();
    playerPointSortList = new Array();
    result = new Array();
    fieldJSON = "";
    _gameTime = 0;
    _order = 1;
    // voiceText[0] and diaryText[0] are for festival result page
    voiceText[0] = "【今回の運動会の結果】";
    diaryText[0] = "\r\n\r\n" //"\r\n\r\=今回の運動会の結果=\r\n";
    resetOrder();
}

function setOrder(tagname){
    var rank = document.getElementById(RANK_ID_PRE + tagname).innerHTML;
    // order setting is valid at once for each rank
    if (rank == "-") {
        document.getElementById(RANK_ID_PRE + tagname).innerHTML = _order;
        _order++;
        result.push(playerList[_gameTime][tagname]);
    }
    // when all order are set, go to next game
    if (_order > FIELD_PLAYER_NUM) {
        resultList.push(result.clone());
        _gameTime++;
        sendActivity(fieldTitle, [result[0], result[1]]);
        // to show last order instantaneously
        setTimeout(setGame, 100);
    }
}


function initializeButton(){
    var resetButton = document.getElementById('resetButton');
    addListener(resetButton, "click", resetOrder);
}

function addListener(elm, type, func){
    if (!elm) {
        return false;
    }
    if (elm.addEventListener) { // W3C準拠ブラウザ用 
        elm.addEventListener(type, func, false);
    }
    else 
        if (elm.attachEvent) { // Internet Explorer用 
            elm.attachEvent('on' + type, func);
        }
        else {
            return false;
        }
    return true;
}

/*
 * when push reset button, all orders are cleared
 */
function resetOrder(){
    _order = 1;
    result = new Array();
    for (var i = 0; i < FIELD_PLAYER_NUM; i++) {
        document.getElementById(RANK_ID_PRE + i).innerHTML = "-";
    }
}

/*
 * initialize and finalize game
 */
function setGame(){
    // all fields have been done
    if (_gameTime >= GAME) {
        finalizeGame();
    }
    else {
        // continue the game
        document.getElementById("lastFieldNum").innerHTML = GAME - _gameTime;
        resetOrder();
        setField();
        setPlayer();
    }
}

/*
 * select players from user's friend
 */
function createPlayerIDList(){
    playersList = new Object();
    inviteFriendIDs = new Array();
    inviteFriendURLs = new Array();
    inviteFriendNames = new Array();
    
    // request viewer's friend
    var fparams = {};
    fparams[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
    fparams[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
    var idSpec = opensocial.newIdSpec(fparams);
    var fetchOpt = {};
    var requestMax = friendNum;
    // At present, the max number of four-fold candidates against FIELD_PLAYER_NUM or all friends will be selected 
    if ((FIELD_PLAYER_NUM * 4) > friendNum) {
        requestMax = FIELD_PLAYER_NUM * 4;
    }
    fetchOpt[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL, opensocial.Person.Field.GENDER, opensocial.Person.Field.HAS_APP];
    fetchOpt[opensocial.DataRequest.PeopleRequestFields.MAX] = requestMax;
    
    // create random number between 0 and friend number minus request number
    var randnom = Math.floor(Math.random() * (friendNum - requestMax));
    if (randnom < 0) {
        randnom = 0;
    }
    // to be more random, sort the friend by name when the random number is odd
    if (randnom % 2 == 1) {
        fetchOpt[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = opensocial.DataRequest.SortOrder.NAME;
    }
    
    fetchOpt[opensocial.DataRequest.PeopleRequestFields.FIRST] = randnom;
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPeopleRequest(idSpec, fetchOpt), "friends");
    
    // make a request
    req.send(function(response){
        if (response.hadError()) {
            var msg = response.getErrorMessage();
            window.alert("初期化に失敗しました。ブラウザの更新ボタンを押してアプリを再読み込みしてください。");
        }
        else {
            var friends = response.get('friends').getData();
            // get total friends number
            friendNum = friends.getTotalSize();
            var playerHTML = "";
            var idNum = 0;
            //
            var tmpPlayerIDList = new Array();
            friends.each(function(friend){
                var playerInfo = new Object();
                var id = friend.getId();
                // people who don't published their profile will be ignored.
                var name = friend.getDisplayName();
                if (friend.getDisplayName() != undefined) {
                    tmpPlayerIDList.push(id);
                    playerInfo[NICKNAME] = friend.getDisplayName();
                    playerInfo[URL] = friend.getField(opensocial.Person.Field.THUMBNAIL_URL);
                    playerInfo[HASAPP] = friend.getField(opensocial.Person.Field.HAS_APP);
                    playersList[id] = playerInfo;
                    
                }
                
            });
            if (tmpPlayerIDList.length < FIELD_PLAYER_NUM * 2) {
                // show alert if the user has friends less than twice of FIELD_PLAYER_NUM
                // [NEED TO MODIFY] fill dummy friends by just that much
                tmpIDList = fillDummyPlayer(FIELD_PLAYER_NUM * 2 - tmpPlayerIDList.length);
                tmpPlayerIDList = tmpPlayerIDList.concat(tmpIDList);
                
            }
            
            // shuffle the candidates of player
            playerIDList = createRandomList(tmpPlayerIDList, FIELD_PLAYER_NUM * 2);
            for (var i = 0; i < playerIDList.length; i++) {
                ///// [NEED TO CHECK] gotyan is added in playerInfo
                var playerInfo = playersList[playerIDList[i]];
                if (playerInfo[HASAPP] == "false") {
                    inviteFriendIDs.push(playerIDList[i]);
                    inviteFriendNames.push(playerInfo[NICKNAME]);
                    inviteFriendURLs.push(playerInfo[URL]);
                };
                document.getElementById("preIDArea" + i).innerHTML = playerInfo[NICKNAME] + "<img src=\"" + playerInfo[URL] + "\" width=50 height=50></img>";
                
            }
            createPlayerList();
            createFieldsList();
            setTimeout(moveToRuleView, 5000);
            
        }
    });
}

/**
 * create an shuffled array of the original one with specific size
 * @param {Object} originalList
 * @param {Object} listSize
 */
function createRandomList(originalList, listSize){
    var newList = [];
    var random;
    for (var i = 0; i < listSize; i++) {
        random = Math.floor(Math.random() * originalList.length);
        newList[i] = originalList[random];
        originalList.splice(random, 1);
    }
    return newList;
}

/**
 * shuffle players' order for each field
 */
function createPlayerList(){
    var fieldPlayer;
    var tmpPlayerList = new Array();
    for (var i = 0; i < GAME_NUM; i++) {
        fieldPlayer = new Array();
        for (var j = 0; j < FIELD_PLAYER_NUM; j++) {
            var k = i + j;
            if (k >= GAME_NUM) {
                k = k - GAME_NUM;
            }
            fieldPlayer.push(playerIDList[k]);
        }
        tmpPlayerList.push(fieldPlayer.clone());
    }
    offset = GAME_NUM / 2;
    //split users to the first and last group and appear alternatively
    for (var j = 0; j < offset; j++) {
        playerList.push(tmpPlayerList[j]);
        playerList.push(tmpPlayerList[j + offset]);
    }
    
}


// This method requests fieldInfo to the server
function createFieldsList(){
    var url = SERVER_NAME + "request/field";
    var params = {};
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    
    gadgets.io.makeRequest(url, function(response){
        if (response.data) {
            fieldJSON = eval("(" + response.data + ")");
            var fieldInfo;
            var fieldID;
            var preFields0 = "<ul>";
            var preFields1 = "<ul>";
            for (var i = 0; i < fieldJSON.length; i++) {
                fieldInfo = new Object();
                fieldID = fieldJSON[i][FIELD_ID].escapeHTML();
                fieldInfo[FIELD_TITLE] = fieldJSON[i][FIELD_TITLE].escapeHTML();
                fieldInfo[FIELD_QUESTION] = fieldJSON[i][FIELD_QUESTION].escapeHTML();
                fieldInfo[FIELD_CATEGORY] = fieldJSON[i][FIELD_CATEGORY];
                fieldsList[fieldID] = fieldInfo;
                fieldIDList.push(fieldID);
                if (i < 5) {
                    preFields0 = preFields0 + "<li>" + fieldJSON[i][FIELD_TITLE].escapeHTML() + "</li>";
                }
                else {
                    preFields1 = preFields1 + "<li>" + fieldJSON[i][FIELD_TITLE].escapeHTML() + "</li>";
                }
            }
            preFields0 += "</ul>";
            preFields1 += "</ul>";
            document.getElementById("preFields0").innerHTML = preFields0;
            document.getElementById("preFields1").innerHTML = preFields1;
            
            setGame();
        }
        else {
            var err = response.errors[0];
            window.alert("タイムアウトしました。しばらく時間をおいてからリロードしてください。");
        }
    }, params);
}


/**
 * set each field information
 */
function setField(){
    var fieldID = fieldIDList[_gameTime];
    var fieldInfo = fieldsList[fieldID];
    fieldTitle = fieldInfo[FIELD_TITLE];
    document.getElementById("fieldNum").innerHTML = "第" + (_gameTime + 1) + "種目";
    document.getElementById('fieldTitle').innerHTML = fieldInfo[FIELD_TITLE] + ":" + fieldInfo[FIELD_QUESTION];
}

/**
 * set player with the name and picture.
 */
function setPlayer(){
    var fieldPlayerList = new Array();
    fieldPlayerList = playerList[_gameTime];
    for (var i = 0; i < fieldPlayerList.length; i++) {
        var playerInfo = new Object();
        var player = fieldPlayerList[i];
        friendInfo = playersList[player];
        document.getElementById("player" + i + "Area").innerHTML = "<span class=\"playerName\" id=\"" + PLAYER_ID_PRE + i + "\">" + friendInfo[NICKNAME] + "</span><br><a href=\"Javascript:setOrder(" + i + ")\"><img class=\"playerPic\" id=\"" + PICTURE_ID_PRE + i + "\" name=\"" + i + "\" src=\"" + friendInfo[URL] + "\"/></a><br><span class=\"playerRanking\" id=\"" + RANK_ID_PRE + i + "\">-</span><span class=\"rankStr\">位</span>";
        initializeButton();
    }
    
}

function setInviteFriend(){
    var html = "";
    for (var i = 0; i < inviteFriendURLs.length; i++) {
        document.getElementById("rIDArea" + i).innerHTML = inviteFriendNames[i] + "<img src=\"" + inviteFriendURLs[i] + "\" width=50 height=50 />";
    }
}

/**
 * set point based on the ranking
 */
function distributePoint(){
    var playerID;
    var point;
    for (var i = 0; i < resultList.length; i++) {
        var result = resultList[i];
        for (var j = 0; j < result.length; j++) {
            // [To Do] consider how to distribute the point, so far 1st:25, 2nd:20, 3rd:15, 4th:10, 5th:5
            playerID = result[j];
            if (playerPointList[playerID] == undefined) {
                point = 0;
            }
            else {
                point = playerPointList[playerID];
            }
            playerPointList[playerID] = point + (5 - j);
        }
    }
}



function finalizeGame(){
    storeStaticPlayerInfo();
    storeUpdatePlayerInfo();
    distributePoint();
    playerPointSortList = sortHash(playerPointList, 1);
    showFestivalResult();
    moveToFestivalFinish();
}

function sortHash(hash, asort){
    // determin hash size
    var hashSize = 0;
    for (var i in hash) {
        hashSize++;
    }
    // create temporary array to sort
    var tmpArray = new Array();
    for (var i in hash) {
        tmpArray.push({
            key: i,
            val: hash[i]
        });
    }
    tmpArray.sort(smallVal);
    function smallVal(a, b){
        if (asort == 0) {
            return (a.val > b.val) ? 1 : -1;
        }
        else {
            return (a.val < b.val) ? 1 : -1;
        }
    }
    var sortHash = new Array();
    var orderHash;
    for (var i = 0; i < tmpArray.length; i++) {
        orderHash = new Array();
        orderHash.push(tmpArray[i].key);
        orderHash.push(tmpArray[i].val);
        sortHash[i] = orderHash.clone();
        
    }
    return sortHash;
}

function showFestivalResult(){
    showPointRankResult();
    showFieldsResult();
    setInviteFriend();
}

/**
 * update player information which is static
 */
function storeStaticPlayerInfo(){
    var REQUEST_URL = SERVER_NAME + "request/updatestatic";
    var params = {};
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    var post_data = {
        myID: myID,
        playerIDList: Object.toJSON(playerIDList)
    };
    params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(post_data);
    gadgets.io.makeRequest(REQUEST_URL, function(response){
        /// no action
    
    }, params);
}

/**
 * update player information which is changable
 */
function storeUpdatePlayerInfo(){
    var fullResultList = new Object();
    for (var i = 0; i < fieldIDList.length; i++) {
        if (resultList[i] == undefined) {
            fullResultList[fieldIDList[i]] = [];
        }
        else {
            fullResultList[fieldIDList[i]] = resultList[i];
        }
    }
    var REQUEST_URL = SERVER_NAME + "request/storeresult";
    var params = {};
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    
    var post_data = {
        myID: myID,
        fieldsList: Object.toJSON(fieldsList),
        fullResultList: Object.toJSON(fullResultList)
    };
    params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(post_data);
    gadgets.io.makeRequest(REQUEST_URL, function(response){
        /// no action
    
    }, params);
}

function showPointRankResult(){
    diaryText[0] += "==総合成績==\r\n";
    for (var i = 0; i < playerPointSortList.length; i++) {
    
        var playerResult = playerPointSortList[i];
        var id = playerResult[0];
        if (i < 3) {
            document.getElementById(POINT_PRE + i).innerHTML = playerResult[1] + "pt";
            document.getElementById(POINT_ID_PRE + i).innerHTML = "<span id=\"pointRankName" + i + "\">" + playersList[id][NICKNAME] + "</span><br><img id=\"pointRankPic" + i + "\" src=\"" + playersList[id][URL] + "\"/>";
            voiceText[0] = voiceText[0] + (i + 1) + "位 " + playerResult[1] + "pt:" + playersList[id][NICKNAME] + ",";
            diaryText[0] = diaryText[0] + playersList[id][NICKNAME] + " ";
            
        }
        else {
            document.getElementById(POINT_ID_PRE + i).innerHTML = playersList[id][NICKNAME];
            document.getElementById(POINT_PRE + i).innerHTML = playerResult[1];
            
        }
        //      diaryText[0] = diaryText[0] + (i + 1) + "位 " + playerResult[1] + "pt:" + playersList[id][NICKNAME] + "\r\n";
    
    }
    diaryText[0] = diaryText[0] + "\r\n\r\n";
    
}

function showFieldsResult(){
    //diaryText[0] += "==種目別順位==\r\n";
    for (var i = 0; i < resultList.length; i++) {
        // Retrieve fieldTitle 
        var fieldID = fieldIDList[i];
        var fieldInfo = fieldsList[fieldID];
        // Set fieldTitle to id=fieldsResultTable on HTML
        document.getElementById(RESULT_FIELD + i).innerHTML = fieldInfo[FIELD_TITLE];
        diaryText[0] = diaryText[0] + "*" + fieldInfo[FIELD_TITLE] + "*\r\n";
        for (var j = 0; j < 3; j++) {
            var id = resultList[i][j];
            document.getElementById(FIELD_RANK_ID_PRE + i + j).innerHTML = playersList[id][NICKNAME];
            //     diaryText[0] = diaryText[0] + (j + 1) + "位: " + playersList[id][NICKNAME] + "  ";
            diaryText[0] = diaryText[0] + playersList[id][NICKNAME] + " ";
            
        }
        diaryText[0] = diaryText[0] + "\r\n\r\n";
    }
    // diaryText[0] += "\r\n";

}


/**


 * following methods aren't used at present.


 * maybe will be use in the future


 */


/* if the browser is IE, return true


 function IsIE() { return (navigator.userAgent.indexOf("MSIE") != -1); }


 */


/* This method is a pair of addListner(elm, type, func)


 function setOrder(ev){


 var tagname = (IsIE()) ? ev.srcElement.name: ev.target.name;


 var rank = document.getElementById(RANK_ID_PRE + tagname).innerHTML;


 // order setting is valid one time for each rank


 if (rank == "-") {


 document.getElementById(RANK_ID_PRE + tagname).innerHTML = _order;


 result.push(playerList[_gameTime][tagname]);


 _order++;


 }


 // when all order are set, go to next game


 if (_order > FIELD_PLAYER_NUM) {


 /// setResult();


 resultList.push(result.clone());


 _gameTime++;


 // setTimeout(setGame,100);


 setGame();


 }


 // initialize order


 }


 */


